package threadDemo;

import org.apache.log4j.Logger;
import org.junit.Test;

import java.util.concurrent.TimeUnit;

/**
 * @author jie
 * @version 创建时间：2018年2月6日 下午10:00:18
 * <p>
 * 类说明 Thread 退出
 * <p>
 * （一）：使用退出标志
 *
 * <p>
 * （二）：使用 interrupt 方法, 不保证能退出。
 * 中断的结果线程是死亡、还是等待新的任务或是继续运行至下一步，就取决于这个程序本身。!!!
 * <p>
 * thread.isInterrupted()
 * 显示线程状态，不变更线程状态
 * <p>
 * https://www.cnblogs.com/myseries/p/10918819.html
 * <p>
 * <p>
 * //已经废弃。 内存状态，资源等不可控
 * * thread.stop();//thread 继续执行 暂停了，当时 (thread == null) false
 * * thread.destroy();//crash thread 调用线程crash thread ，但线程继续执行。
 */
public class ThreadExitDemo {
    static int i;
    private static final Logger logger = Logger.getLogger(ThreadExitDemo.class);


    //    public static void mainJavaAPI(String[] args) {
    public static void main(String[] args) {
        final long[] start = {System.currentTimeMillis()};
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    long current = System.currentTimeMillis();
                    if (current - start[0] > 500) {
                        logger.info("run: thred is running");
                        start[0] = current;
                    }
                }
            }
        });
        thread.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //已经废弃。
        thread.stop();//thread 继续执行 暂停了，当时 (thread == null) false
//		thread.destroy();//crash thread 继续执行。
        logger.info("main: " + (thread == null));
    }

    public static volatile boolean exit = false;  //退出标志

    //（一）：使用退出标志
    @Test
    public void exitFlag() {
        new Thread() {
            public void run() {
                System.out.println("线程启动了");
                while (!exit) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("线程结束了");
            }
        }.start();

        try {
            Thread.sleep(1000 * 5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        exit = true;//5秒后更改退出标志的值,没有这段代码，线程就一直不能停止
    }

    public static void mainIsInterrupted(String[] args) {
        Thread thread = new Thread() {
            public void run() {
                System.out.println("线程启动了");
                while (!this.isInterrupted()) {
                    System.out.println(isInterrupted());//调用 interrupt 之后为true
                }
                System.out.println("线程结束了");
            }
        };
        thread.start();

        try {
            Thread.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread.interrupt();
        System.out.println("线程是否被中断：" + thread.isInterrupted());//true
        System.out.println("线程是否被中断：" + thread.isInterrupted());//true
    }

    //TODO 线程一直是 中断 状态，当时整成运行。因为没有响应中断 变量。
    public static void mainTestInterruptCantExit(String[] args) {
//    public static void main(String[] args) {

        final long[] start = {System.currentTimeMillis()};
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    long current = System.currentTimeMillis();
                    if (current - start[0] > 2000) {
                        logger.info("run: thred is running");
                        start[0] = current;
                    }
                }
            }
        });

        //没有响应 interrupt 的阻塞状态
        thread.start();
        logger.info("main: interrupt before: " + thread.isInterrupted());//false
        thread.interrupt();
        logger.info("main: interrupt after: " + thread.isInterrupted());//true
        logger.info("main: interrupt after 2: " + thread.isInterrupted());//一直为 true ，因为状态【标志位】没有改变。
    }

    public static void mainInterruptOnce(String[] args) {
//    public static void main(String[] args) {

        final long[] start = {System.currentTimeMillis()};
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    long current = System.currentTimeMillis();

                    try {
                        TimeUnit.SECONDS.sleep(5);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (current - start[0] > 2000) {
                        logger.info("run: thred is running");
                        start[0] = current;
                    }
                }
            }
        });

        thread.start();
        logger.info("main: interrupt before: " + thread.isInterrupted());//false ,不是中断状态。
        thread.interrupt();
        logger.info("main: interrupt after: " + thread.isInterrupted());//true ，是中断状态。中断了 sleep
        logger.info("main: interrupt after 2: " + thread.isInterrupted());//false ，恢复为非中断状态。

    }

    //（二）：使用 interrupt 方法
    public static void mainInterruptExit(String[] args) {
        logger.info("interruptExit: start");
        Thread thread = new Thread() {
            public void run() {
                System.out.println("线程启动了");
                try {
                    Thread.sleep(1000 * 5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程结束了1");

                boolean interrupted = Thread.currentThread().isInterrupted();
                try {
                    Thread.sleep(1000 * 5);
                } catch (InterruptedException e) {
                    logger.info("run: 第二个终端 Exception");
                    e.printStackTrace();
                }
                System.out.println("线程结束了2");

            }
        };
        thread.start();

        try {
            Thread.sleep(1000 * 4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        logger.info("mainInterruptExit: before" + thread.isInterrupted());
        thread.interrupt();//作用是：在线程阻塞时抛出一个中断信号，这样线程就得以退出阻塞的状态
        logger.info("mainInterruptExit: " + thread.isInterrupted());
        logger.info("mainInterruptExit: ");
    }


}


